home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / cardfile / part02 < prev    next >
Encoding:
Text File  |  1990-10-14  |  57.9 KB  |  2,337 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: dplace!pacbell!djl@PacBell.COM
  3. from: Dave Lampe <dplace!djl@PacBell.COM>
  4. subject: v15i050: cardfile - part 2 of 3
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 50
  8. Submitted-by: Dave Lampe <dplace!djl@PacBell.COM>
  9. Archive-name: cardfile/part02
  10.  
  11. ---- Cut Here and feed the following to sh ----
  12. #!/bin/sh
  13. # This is part 02 of cardfile
  14. # ============= getkey.c ==============
  15. echo 'x - extracting getkey.c (Text)'
  16. sed 's/^X//' << 'SHAR_EOF' > 'getkey.c' &&
  17. X#ifndef lint
  18. Xstatic char Sccsid[] = "@(#)getkey.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  19. X#endif
  20. X
  21. X/*      GETKEY.C        */
  22. X/*      This subroutine is used to search an alternate key file
  23. X        to find records matching the input value. It returns the
  24. X        offset of the record in the DB file if found, or -1 if
  25. X        no match was found.
  26. X*/
  27. X#include "stdio.h"
  28. X#include "cardfile.h"
  29. X#include "ascii.h"
  30. X
  31. Xdiskptr
  32. Xgetkey(file, val)
  33. XFILE    *file;
  34. Xchar    *val;
  35. X{
  36. X    static char *match;
  37. X    char        rcd[AKSIZE];
  38. X    long        atol();
  39. X    char        *fgets();
  40. X    int    rc;
  41. X    
  42. X    if (val != 0) {     /* first time */
  43. X        match = val;
  44. X        fseek(file, 0L, 0);
  45. X    }
  46. X    while (fgets(rcd, AKSIZE, file) != NULL) {
  47. X        if ((rc = keymatch(rcd, match)) == -1) {
  48. X        break;
  49. X    } else if (rc == 1) {
  50. X            return (atol(strchr(rcd, ':')+1));
  51. X        }
  52. X    }
  53. X    return (-1L);
  54. X}
  55. SHAR_EOF
  56. true || echo 'restore of getkey.c failed'
  57. # ============= keymatch.c ==============
  58. echo 'x - extracting keymatch.c (Text)'
  59. sed 's/^X//' << 'SHAR_EOF' > 'keymatch.c' &&
  60. X#ifndef lint
  61. Xstatic char Sccsid[] = "@(#)keymatch.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  62. X#endif
  63. X
  64. X/*    KEYMATCH.C      */
  65. X/*    This subroutine is used to test if the key in the AK file
  66. X**    record matches the input value. Two options are supported,
  67. X**    UNIX style regular expressions or simple matches. If 'BSD_RE',
  68. X**    'SYSV_RE', or 'PD_RE' is defined regular expressions are allowed.
  69. X**    If the input value is enclosed in quotes an exact match is
  70. X**    required, otherwise upper/lower case is ignored. If simple
  71. X**    matching is being done, 'NO_RE', an '*' at the end of an unquoted
  72. X**    string matches everything.
  73. X**/
  74. X#include "cardfile.h"
  75. X
  76. X#ifdef BSD_RE
  77. Xextern    char    *re_comp();
  78. Xextern    int    re_exec();
  79. X#endif
  80. X#ifdef SYSV_RE
  81. Xextern    char    *regcmp();
  82. Xextern    char    *regex();
  83. X#endif
  84. X#ifdef PD_RE
  85. X#include <regexp.h>
  86. Xextern    regexp    *regcomp();
  87. Xextern    int    regexec();
  88. X#endif
  89. X
  90. Xstatic    strlower();
  91. X
  92. Xkeymatch(akrcd, val)
  93. Xchar    *akrcd, *val;
  94. X{
  95. X    register int vlen;
  96. X    char    convert[256];
  97. X    char    key[256];
  98. X    static int    lower;
  99. X#ifdef SYSV_RE
  100. X    static char    lastval[256];
  101. X    static char    *cval;
  102. X#endif
  103. X#ifdef PD_RE
  104. X    static char    lastval[256];
  105. X    static regexp *cval;
  106. X#endif
  107. X#ifdef BSD_RE
  108. X    static char    lastval[256];
  109. X# endif
  110. X#ifdef NO_RE
  111. X    register char *cp = convert,
  112. X          *kp = key;
  113. X#endif
  114. X    
  115. X#ifdef NO_RE
  116. X    vlen = strlen(val);
  117. X    strcpy(convert, val);
  118. X    if ((*convert == '"' && convert[vlen-1] == '"')
  119. X    || (*convert == '\'' && convert[vlen-1] == '\'')) {
  120. X    strcpy(convert, convert+1);
  121. X    convert[vlen-2] = '\0';
  122. X    lower = 0;
  123. X    } else {
  124. X    strlower(convert);
  125. X    lower = 1;
  126. X    }
  127. X    strcpy(key, akrcd);
  128. X    *strchr(key, ':') = '\0';
  129. X    if (lower) {
  130. X    strlower(key);
  131. X    }
  132. X    while (*cp != '\0' && (lower == 0 || *cp != '*')) {
  133. X    if (*cp != *kp)
  134. X        return(0);
  135. X    ++cp;
  136. X    ++kp;
  137. X    }
  138. X    if (*cp == '\0' && *kp != '\0')
  139. X    return(0);
  140. X    return(1);
  141. X#else    /* BSD_RE | SYSV_RE | PD_RE */
  142. X    if (strcmp(val, lastval) != 0) {        /* new pattern */
  143. X    vlen = strlen(val);
  144. X# ifndef BSD_RE        /* SYSV_RE | PD_RE */
  145. X    if (cval)        /* free last pattern if any */
  146. X        free (cval);
  147. X# endif
  148. X    strcpy(lastval, val);
  149. X    strcpy(convert, val);
  150. X    if ((*convert == '"' && convert[vlen-1] == '"')
  151. X        || (*convert == '\'' && convert[vlen-1] == '\'')) {
  152. X        strcpy(convert, convert+1);
  153. X        convert[vlen-2] = '\0';
  154. X        lower = 0;
  155. X    } else {
  156. X        strlower(convert);
  157. X        lower = 1;
  158. X    }
  159. X# ifdef BSD_RE
  160. X    if (re_comp(convert) != 0) {
  161. X# endif
  162. X# ifdef SYSV_RE
  163. X    if ((cval = regcmp(convert, 0)) == 0) {
  164. X# endif
  165. X# ifdef PD_RE
  166. X    if ((cval = regcomp(convert)) == 0) {
  167. X# endif
  168. X        msg("Invalid search pattern");
  169. X        return(-1);
  170. X    }
  171. X    }
  172. X    strcpy(key, akrcd);
  173. X    *strchr(key, ':') = '\0';
  174. X    if (lower) {
  175. X    strlower(key);
  176. X    }
  177. X# ifdef BSD_RE
  178. X    if (re_exec(key) != 0) {
  179. X# endif
  180. X# ifdef SYSV_RE
  181. X    if (regex(cval, key) != 0) {
  182. X# endif
  183. X# ifdef PD_RE
  184. X    if (regexec(cval, key) != 0) {
  185. X# endif
  186. X        return(1);
  187. X    }
  188. X    return(0);
  189. X#endif    /* RE */
  190. X}
  191. X
  192. X
  193. Xstatic
  194. Xstrlower(str)
  195. Xregister char    *str;
  196. X{
  197. X
  198. X    while (*str) {
  199. X    if (*str >= 'A' && *str <= 'Z')
  200. X        *str = *str - 'A' + 'a';
  201. X    ++str;
  202. X    }
  203. X}
  204. SHAR_EOF
  205. true || echo 'restore of keymatch.c failed'
  206. # ============= maint.c ==============
  207. echo 'x - extracting maint.c (Text)'
  208. sed 's/^X//' << 'SHAR_EOF' > 'maint.c' &&
  209. X#ifndef lint
  210. Xstatic char Sccsid[] = "@(#)maint.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  211. X#endif
  212. X
  213. X/*      MAINT.C         */
  214. X/*      This module is displays the maintenance menu and
  215. X        controls the execution of the associated routines
  216. X*/
  217. X#include "stdio.h"
  218. X#include "cardfile.h"
  219. X
  220. Xchar    *mfuncts[]   = {"EXIT        ",
  221. X                        "DUMP        ",
  222. X                        "COMPRESS    ",
  223. X                        "REBUILD AK's",
  224. X                        "EXTRACT     ",
  225. X                        0
  226. X                        };
  227. X#define DUMP    1
  228. X#define COMPRES 2
  229. X#define RBUILD  3
  230. X#define EXTRACT 4
  231. X#define EXIT    0
  232. X
  233. X
  234. Xmaint(fields, dbname, ak_data)
  235. Xstruct  Fdata   *fields;
  236. Xchar    *dbname;
  237. Xstruct  AKdata  *ak_data;
  238. X{
  239. X    char        first[SWIDTH];
  240. X    int         func;
  241. X    
  242. X    sprintf(first, "Maintenance functions for %s", dbname);
  243. X    while ((func = menu(first, mfuncts)) != EXIT) {
  244. X        switch (func) {
  245. X        case DUMP:
  246. X            dumpdb(dbname, ak_data, fields);
  247. X            continue;
  248. X        case COMPRES:
  249. X            compress(dbname);
  250. X            rbuildak(dbname, ak_data, fields);
  251. X            continue;
  252. X        case RBUILD:
  253. X            rbuildak(dbname, ak_data, fields);
  254. X            continue;
  255. X        case EXTRACT:
  256. X            extract(fields, dbname);
  257. X            continue;
  258. X        default:
  259. X            msg("Illegal function chosen");
  260. X        }
  261. X    }
  262. X}
  263. SHAR_EOF
  264. true || echo 'restore of maint.c failed'
  265. # ============= menu.c ==============
  266. echo 'x - extracting menu.c (Text)'
  267. sed 's/^X//' << 'SHAR_EOF' > 'menu.c' &&
  268. X#ifndef lint
  269. Xstatic char Sccsid[] = "@(#)menu.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  270. X#endif
  271. X
  272. X/*    MENU.C        */
  273. X/*    This subroutine is used to display a menu of commands
  274. X**    and wait for the user to select one.
  275. X**    It returns the number of the command selected.
  276. X**/
  277. X#include "cardfile.h"
  278. X
  279. Xmenu(dbname, functs)
  280. Xchar    *dbname;
  281. Xchar    **functs;
  282. X{
  283. X    int         func;
  284. X    char        dummy[2];
  285. X    struct      Sdata   *sp, *mscreen;
  286. X    char    *malloc();
  287. X
  288. X    mscreen = (struct Sdata*)malloc((MAXFLDS+1) * sizeof(struct Sdata));
  289. X    sp = mscreen;
  290. X    do {
  291. X        sp->S_title = *functs;
  292. X        sp->S_length = 1;
  293. X        sp->S_result = dummy;
  294. X        sp->S_dfault = 0;
  295. X    sp->S_page = -1;
  296. X    sp->S_Lrow = -1;
  297. X    sp->S_Lcol = -1;
  298. X    sp->S_Drow = -1;
  299. X    sp->S_Dcol = -1;
  300. X    sp->S_Dfmt = "";
  301. X        ++sp;
  302. X    } while (*++functs);
  303. X    sp->S_title = 0;
  304. X    screen(dbname, mscreen, 0, &func, FALSE);
  305. X    free((char*)mscreen);
  306. X    return (func);
  307. X}
  308. SHAR_EOF
  309. true || echo 'restore of menu.c failed'
  310. # ============= printdb.c ==============
  311. echo 'x - extracting printdb.c (Text)'
  312. sed 's/^X//' << 'SHAR_EOF' > 'printdb.c' &&
  313. X#ifndef lint
  314. Xstatic char Sccsid[] = "@(#)printdb.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  315. X#endif
  316. X
  317. X/*      PRINTDB.C       */
  318. X/*      This module format prints the data base in the order requested.
  319. X**      NOTE: If a record contains multiple values for the key selected,
  320. X**      it will be printed multiple times.
  321. X**      Alternativly it will format print an extracted file (see extract.c)
  322. X**      The formats allowed are:
  323. X**        %NN     - contents of field NN (1-maxfield)
  324. X**        %NN(form) - contents of field NN in printf '%form' format
  325. X**        %n      - new-line
  326. X**        %t      - tab
  327. X**        %f      - form feed
  328. X**        %t(NN)  - tab to column NN
  329. X**        %%      - %
  330. X**      NOTE: '.' ends a format specification %1.1 prints the contents of
  331. X**      field 1 concatenated with a '1'.
  332. X**/
  333. X#include "stdio.h"
  334. X#include "cardfile.h"
  335. X#include "ascii.h"
  336. X#include <signal.h>
  337. X
  338. Xchar    out_format[512], ext_file[15];
  339. Xchar    out_file[15], out_width[4];
  340. Xstruct  Sdata   first_screen[] = {
  341. X            {"Format", 127, out_format, 0, -1, -1, -1, -1, -1, ""},
  342. X            {"Extracted File", 14, ext_file, 0, -1, -1, -1, -1, -1, ""},
  343. X            {"Output File", 14, out_file, 0, -1, -1, -1, -1, -1, ""},
  344. X            {"Output Width", 3, out_width, 0, -1, -1, -1, -1, -1, ""},
  345. X            {0, 0, 0, 0, -1, -1, -1, -1, -1, ""}
  346. X        };
  347. X
  348. Xstatic    int    quit = 0;
  349. Xstatic    SIGRTN    (*old_sig)();
  350. Xstatic    FILE    *out;
  351. Xstatic    SIGRTN    abort();
  352. X
  353. X
  354. Xprintdb(fields, dbname)
  355. Xstruct  Fdata *fields;
  356. Xchar    *dbname;
  357. X{
  358. X    char    *keys[MAXAK+1];
  359. X    char    keyv[MAXAK][TSIZE+1];
  360. X    int     nkeys, i;
  361. X    struct      Fdata *fp;
  362. X    char    aknum[MAXAK];
  363. X    int     keynum;
  364. X    char    title[SWIDTH];
  365. X    char    fname[FNSIZE];
  366. X    FILE    *akfile, *dbfile;
  367. X    char    akrec[AKSIZE+1], dbrec[DBSIZE+1];
  368. X    long    offset, atol();
  369. X    int     width;
  370. X    char    *last;
  371. X    char    h_line[1024];
  372. X
  373. X    sprintf(title, "Print %s data base", dbname);
  374. X    while (1) {
  375. X    last = "Enter ? for help.";
  376. X        screen(title, first_screen, last, 0, FALSE);
  377. X        if (strcmp(ext_file, "?") == 0) {
  378. X        strcpy(h_line, "Enter the name of the extract file generated");
  379. X        strcat(h_line, " from\nthe maintenance menu. If you leave it");
  380. X        strcat(h_line, " blank, the entire\ndata base will be dumped.");
  381. X        help(h_line);
  382. X        continue;
  383. X        }
  384. X        if (strcmp(out_width, "?") == 0) {
  385. X        help("Enter the width of the output device, defaults to 80.");
  386. X        continue;
  387. X        }
  388. X        if (*out_width == '\0') {
  389. X        width = PWIDTH;
  390. X        } else {
  391. X        width = atoi(out_width);
  392. X        }
  393. X        if (strcmp(out_file, "?") == 0) {
  394. X        strcpy(h_line, "Enter the name of the output file,");
  395. X        strcat(h_line, " defaults to '|lp', the printer.");
  396. X        help(h_line);
  397. X        continue;
  398. X        }
  399. X        if (*out_file == '\0') {
  400. X        strcpy(out_file, "|lp");
  401. X        }
  402. X        if (strcmp(out_format, "?") == 0) {
  403. X        strcpy(h_line, "Enter the output format. All characters will");
  404. X        strcat(h_line, " be\nprinted as entered except for % sequences.");
  405. X        strcat(h_line, "\n\n\t%NN\t - contents of field NN (1-maxfield)");
  406. X        strcat(h_line, "\n\t%NN(form) - contents of field NN in");
  407. X            strcat(h_line, " printf '%form' format\n");
  408. X        strcat(h_line, "\t%n\t- new-line\n");
  409. X        strcat(h_line, "\t%t\t- tab\n");
  410. X        strcat(h_line, "\t%t(NN)\t- tab to column NN\n");
  411. X        strcat(h_line, "\t%f\t- form-feed\n");
  412. X        strcat(h_line, "\t%%\t- %");
  413. X        help(h_line);
  414. X        continue;
  415. X        }
  416. X        if (*out_format == '\0') {  /* not specified, use default */
  417. X        fp = fields;
  418. X        i = 1;
  419. X        while (fp->F_title[0]) {
  420. X        sprintf(&out_format[strlen(out_format)], "%s: %%%d%%n",
  421. X            fp->F_title, i);
  422. X        ++i;
  423. X        ++fp;
  424. X        }
  425. X        strcat(out_format, "%n%n%n");
  426. X    }
  427. X    break;
  428. X    }
  429. X    if (ext_file[0] == '\0') {
  430. X    msg("No extract specified, entire database will be dumped");
  431. X    }
  432. X    fp = fields;
  433. X    nkeys = 0;
  434. X    if (ext_file[0] == '\0') {
  435. X    while (fp->F_title[0] != '\0') {
  436. X        if (fp->F_key != 'N') {
  437. X        sprintf(keyv[nkeys], "%-20s", fp->F_title);
  438. X        keys[nkeys] = keyv[nkeys];
  439. X        aknum[nkeys] = fp->F_key;
  440. X        ++nkeys;
  441. X        }
  442. X        ++fp;
  443. X    }
  444. X    keys[nkeys] = "Cancel              ";
  445. X    aknum[nkeys] = '\0';
  446. X    ++nkeys;
  447. X    keys[nkeys] = 0;
  448. X    sprintf(title, "Print %s data base selected by", dbname);
  449. X    keynum = menu(title, keys);
  450. X    if (aknum[keynum] == '\0') {    /* cancel */
  451. X        return(1);
  452. X    }
  453. X    if (*out_file == '|')
  454. X        out = popen(out_file+1, "w");
  455. X    else
  456. X        out = fopen(out_file, "w");
  457. X    if (out == NULL) {
  458. X        msg("Unable to open output file");
  459. X        return(1);
  460. X    }
  461. X
  462. X    sprintf(fname, "%s%s.ak%c", datadir, dbname, aknum[keynum]);
  463. X    if ((akfile = fopen(fname, "r")) == NULL) {
  464. X        msg("Unable to open alternate key file");
  465. X        getout();
  466. X    }
  467. X    sprintf(fname, "%s%s.db", datadir, dbname);
  468. X    if ((dbfile = fopen(fname, "r")) == NULL) {
  469. X        msg("Unable to open db file");
  470. X        getout();
  471. X    }
  472. X    msg(NULL);    /* leave the cursor at the bottom */
  473. X    fputs("DEL to abort printing", stdout);
  474. X    old_sig = signal(SIGINT, abort);
  475. X
  476. X    while(!quit && fgets(akrec, AKSIZE, akfile) != NULL) {
  477. X        offset = atol(strchr(akrec, ':')+1);
  478. X        if (offset < 0L)
  479. X        continue;
  480. X        fseek(dbfile, offset, 0);
  481. X        if (fgets(dbrec, DBSIZE, dbfile) == NULL) {
  482. X        msg("Bad offset found");
  483. X        continue;
  484. X        }
  485. X        if (*dbrec == 'D')  /* check for delete flag */
  486. X        continue;
  487. X        if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
  488. X        break;
  489. X    }
  490. X    fclose(akfile);
  491. X    } else {
  492. X    if ((dbfile = fopen(ext_file, "r")) == NULL) {
  493. X        msg("Unable to read extract file");
  494. X        return(1);
  495. X    }
  496. X    if (*out_file == '|')
  497. X        out = popen(out_file+1, "w");
  498. X    else
  499. X        out = fopen(out_file, "w");
  500. X    if (out == NULL) {
  501. X        msg("Unable to open output file");
  502. X        return(1);
  503. X    }
  504. X    msg(NULL);    /* leave the cursor at the bottom */
  505. X    fputs("DEL to abort printing", stdout);
  506. X    old_sig = signal(SIGINT, abort);
  507. X    while(!quit && fgets(dbrec, DBSIZE, dbfile) != NULL) {
  508. X        if (putrcd(0, dbrec, out, out_format, width, 1) == -1)
  509. X        break;
  510. X    }
  511. X    fclose(dbfile);
  512. X    }
  513. X    fclose(dbfile);
  514. X    if (*out_file == '|')
  515. X    pclose(out);
  516. X    else
  517. X    fclose(out);
  518. X    signal(SIGINT, old_sig);
  519. X    if (quit)
  520. X    return(1);
  521. X    else
  522. X    return(0);
  523. X}
  524. X
  525. X
  526. Xstatic SIGRTN
  527. Xabort()
  528. X{
  529. X
  530. X    fputs("\n\nOUTPUT ABORTED!\n", out);
  531. X    msg("Dump aborted");
  532. X    quit = 1;
  533. X}
  534. SHAR_EOF
  535. true || echo 'restore of printdb.c failed'
  536. # ============= putrcd.c ==============
  537. echo 'x - extracting putrcd.c (Text)'
  538. sed 's/^X//' << 'SHAR_EOF' > 'putrcd.c' &&
  539. X#ifndef lint
  540. Xstatic char Sccsid[] = "@(#)putrcd.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  541. X#endif
  542. X
  543. X/*      PUTRCD.C        */
  544. X/*      This subroutine is used to format print a record
  545. X *      Input is :
  546. X *          1) An optional pointer to the header to be printed
  547. X *          2) A pointer to the field structures defining the record
  548. X *          3) A pointer to the record
  549. X *          4) The output file
  550. X *          5) The format of the output
  551. X *          6) The width of a line on the output device
  552. X *          7) The line spacing
  553. X *      It returns the number of lines printed.
  554. X *      The format is specified in "printdb.c"
  555. X */
  556. X#include "stdio.h"
  557. X#include "cardfile.h"
  558. X
  559. Xputrcd(first, rcd, file, fmt, width, space)
  560. Xchar    *first, *rcd;
  561. XFILE    *file;
  562. Xchar    *fmt;
  563. Xint     width, space;
  564. X{
  565. X    char        *fmt_ptr;
  566. X    char        *fld_ptr[MAXFLDS+2];
  567. X    char        fmtspec[25];
  568. X    int         i, field;
  569. X    int        max_flds;
  570. X    int         atcol, tocol;
  571. X    int         state;
  572. X    char    *getfield();
  573. X#define COPY    0
  574. X#define ESC     1
  575. X#define FIELD   2
  576. X    
  577. X    if (first != 0) {
  578. X        fprintf(file, "          %s", first);
  579. X        for (i=0; i<space; i++)
  580. X            putc('\n', file);
  581. X    }
  582. X    rcd[strlen(rcd)-1] = '\0';  /* throw away \n */
  583. X    getfield(rcd, ":"); /* throw away flag */
  584. X    i = 1;
  585. X    /* get position of all fields */
  586. X    while ((fld_ptr[i++]=getfield(0, ":")) != NULL) ;
  587. X    max_flds = --i;
  588. X    /* analyze format string */
  589. X    state = COPY;
  590. X    atcol = 1;
  591. X    fmt_ptr = fmt;
  592. X    while (*fmt != '\0') {
  593. X        switch (state) {
  594. X        case COPY:
  595. X            if (*fmt == '%') {
  596. X                state = ESC;
  597. X            } else {
  598. X                putc(*fmt, file);
  599. X                ++atcol;
  600. X            }
  601. X            ++fmt;
  602. X            break;
  603. X        case ESC:
  604. X            if (*fmt == 'n') {                          /* %n */
  605. X                for (i=0; i<space; i++)
  606. X                    putc('\n', file);
  607. X                atcol = 1;
  608. X                state = COPY;
  609. X            } else if (*fmt == 'f') {                   /* %f */
  610. X                putc('\f', file);
  611. X                atcol = 1;
  612. X                state = COPY;
  613. X            } else if (*fmt == 't') {                   /* %t */
  614. X                if (*(fmt+1) == '(') {          /* %t(NN) */
  615. X                    fmt += 2;   /* point past '(' */
  616. X                    tocol = atoi(fmt);
  617. X                    if (tocol < atcol) {
  618. X                        fmt_error(fmt_ptr, fmt-fmt_ptr);
  619. X                        return(-1);
  620. X                    }
  621. X                    while (atcol++ < tocol) {   /* space to correct column */
  622. X                        putc(' ', file);
  623. X                    }
  624. X                    /* move past column specifier in format */
  625. X                    while (*fmt >'0' && *fmt <= '9') {
  626. X                        ++fmt;
  627. X                    }
  628. X                } else {                        /* %t */
  629. X                    putc('\t', file);
  630. X                    atcol += 8 - (atcol-1)%8;
  631. X                }
  632. X                state = COPY;
  633. X            } else if (*fmt == '%') {                   /* %% */
  634. X                state = COPY;
  635. X                ++atcol;
  636. X                putc('%', file);
  637. X            } else if (*fmt >= '0' && *fmt <= '9') {    /* %NN */
  638. X                state = FIELD;
  639. X                field = atoi(fmt);
  640. X        if (field > max_flds) {
  641. X            fmt_error(fmt_ptr, fmt-fmt_ptr);
  642. X            return(-1);
  643. X        }
  644. X                while (*(fmt+1) >= '0' && *(fmt+1) <= '9')
  645. X                    ++fmt;
  646. X            } else {
  647. X                fmt_error(fmt_ptr, fmt-fmt_ptr);
  648. X                return(-1);
  649. X            }
  650. X            ++fmt;
  651. X            break;
  652. X        case FIELD:
  653. X            strcpy(fmtspec, "%s");
  654. X            if (*fmt == '(') {  /* special format */
  655. X                ++fmt;
  656. X                strncpy(fmtspec, fmt, (i = strchr(fmt, ')') - fmt));
  657. X                fmtspec[i] = '\0';
  658. X                fmt += i + 1;
  659. X                if(putfield(file, fld_ptr[field], fmtspec, &atcol, width) == -1)
  660. X                    return(-1);
  661. X            } else {            /* default string format */
  662. X                if(putfield(file, fld_ptr[field], fmtspec, &atcol, width) == -1)
  663. X                    return(-1);
  664. X                if (*fmt == '.') {
  665. X                    ++fmt;
  666. X                }
  667. X            }
  668. X            state = COPY;
  669. X            break;
  670. X        }
  671. X    }
  672. X    return(0);
  673. X}
  674. X
  675. X    
  676. X/*
  677. X * Print a field in default format
  678. X */
  679. Xputfield(outfile, fld, outfmt, colptr, width)
  680. XFILE    *outfile;
  681. Xchar    *fld;
  682. Xchar    *outfmt;
  683. Xint     *colptr;
  684. Xint     width;
  685. X{
  686. X    int         cleft;          /* number of characters left on line */
  687. X    char        format[64];
  688. X    char        outstr[512];
  689. X    double      atof();
  690. X    long        atol();
  691. X
  692. X    if (fld == NULL)
  693. X        return(0);
  694. X    cleft = width - *colptr;
  695. X    while (strlen(fld) > cleft) {       /*break field if too long for 1 line */
  696. X        if (*(fld+cleft) == ' ' || *(fld+cleft) == ',' || cleft <= 10) {
  697. X            if (cleft <= 10)
  698. X                cleft = width - *colptr;        /* reset to use full line */
  699. X            sprintf(format, "%%.%ds\n", cleft);
  700. X            fprintf(outfile, format, fld);
  701. X            fld += cleft;
  702. X            cleft = width;
  703. X            *colptr = 1;
  704. X            continue;
  705. X        }
  706. X        --cleft;
  707. X    }
  708. X    switch (outfmt[strlen(outfmt)-1]) {
  709. X    case 's':
  710. X        sprintf(outstr, outfmt, fld);
  711. X        break;
  712. X    case 'f':
  713. X    case 'e':
  714. X    case 'E':
  715. X    case 'g':
  716. X    case 'G':
  717. X        sprintf(outstr, outfmt, atof(fld));
  718. X        break;
  719. X    case 'd':
  720. X    case 'u':
  721. X    case 'o':
  722. X    case 'x':
  723. X    case 'X':
  724. X        sprintf(outstr, outfmt, atoi(fld));
  725. X        break;
  726. X    default:
  727. X        printf("unknown format '%s'\n", outfmt);
  728. X        return(-1);
  729. X    }
  730. X    *colptr += strlen(outstr);
  731. X    fprintf(outfile, "%s", outstr);
  732. X    return(0);
  733. X}
  734. X
  735. X
  736. Xfmt_error(fmt, col)
  737. Xchar    *fmt;
  738. Xint     col;
  739. X{
  740. X    char    str[200];
  741. X
  742. X    sprintf(str, "format='%s'   Error near column %d", fmt, col);
  743. X    msg(str);
  744. X    sleep(4);
  745. X}
  746. SHAR_EOF
  747. true || echo 'restore of putrcd.c failed'
  748. # ============= rawio.c ==============
  749. echo 'x - extracting rawio.c (Text)'
  750. sed 's/^X//' << 'SHAR_EOF' > 'rawio.c' &&
  751. X#ifndef lint
  752. Xstatic char Sccsid[] = "@(#)rawio.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  753. X#endif
  754. X
  755. X/*    RAWIO.C        */
  756. X
  757. X#include "ascii.h"
  758. X#include "cardfile.h"
  759. X
  760. Xstatic int    echo_f = 1;
  761. X
  762. Xint
  763. Xrawgetchar()
  764. X{
  765. X    int        ch;
  766. X    
  767. X    ch = getchar();
  768. X    if (ch == DEL) {
  769. X    msg("Again to quit");
  770. X    if ((ch = getchar()) == DEL)
  771. X        getout();
  772. X    msg("");
  773. X    resetcursor();
  774. X    }
  775. X    if (echo_f)
  776. X    rawputchar(ch);
  777. X    return (ch);
  778. X}
  779. X
  780. Xrawputchar(ch)
  781. Xchar    ch;
  782. X{
  783. X    putchar(ch);
  784. X}
  785. X
  786. Xecho()
  787. X{
  788. X    echo_f = 1;
  789. X}
  790. X
  791. Xnoecho()
  792. X{
  793. X    echo_f = 0;
  794. X}
  795. SHAR_EOF
  796. true || echo 'restore of rawio.c failed'
  797. # ============= rbuildak.c ==============
  798. echo 'x - extracting rbuildak.c (Text)'
  799. sed 's/^X//' << 'SHAR_EOF' > 'rbuildak.c' &&
  800. X#ifndef lint
  801. Xstatic char Sccsid[] = "@(#)rbuildak.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  802. X#endif
  803. X
  804. X/*    RBUILDAK.C      */
  805. X/*    This module will rebuild the alternate key files.
  806. X**    It requires only the DEF and DB files. It must be
  807. X**    used after a compress, if the DB file has been edited,
  808. X**    or if the DEF file is changed affecting the key fields.
  809. X*/
  810. X#include "stdio.h"
  811. X#include "cardfile.h"
  812. X
  813. Xrbuildak(dbname, ak_data, fields)
  814. Xchar    *dbname;
  815. Xstruct  AKdata  *ak_data;
  816. Xstruct  Fdata   *fields;
  817. X{
  818. X    FILE    *dbfile, *akfile;
  819. X    char    fname[FNSIZE], rec[DBSIZE];
  820. X    long    offset, ftell();
  821. X    char    *buffer, *malloc();
  822. X    
  823. X    while (ak_data->A_fldnum >= 0) {
  824. X    sprintf(fname, "%s%s", datadir, ak_data->A_akname);
  825. X    if ((akfile=fopen(fname, "w")) == NULL) {;   /* truncate file */
  826. X        msg("Unable to write the database");
  827. X        getout();
  828. X    }
  829. X    fclose(akfile);
  830. X    ++ak_data;
  831. X    }
  832. X    sprintf(fname, "%s%s.db", datadir, dbname);
  833. X    dbfile = fopen(fname, "r");
  834. X    buffer = malloc(BUFSIZE);
  835. X    if (buffer == NULL) {
  836. X    msg("Unable to allocate buffer space");
  837. X    getout();
  838. X    }
  839. X    *buffer = '\0';
  840. X    while ((offset = ftell(dbfile)) >= 0L &&
  841. X    fgets(rec, DBSIZE, dbfile) != NULL) {
  842. X    if (feof(dbfile))
  843. X        break;
  844. X    rec[strlen(rec)-1] = '\0';      /* truncate new-line */
  845. X    buildak(dbname, strchr(rec,':')+1, offset, fields, buffer);
  846. X    }
  847. X    fclose(dbfile);
  848. X    writeak(dbname, buffer);
  849. X    free(buffer);
  850. X}
  851. SHAR_EOF
  852. true || echo 'restore of rbuildak.c failed'
  853. # ============= screen.c ==============
  854. echo 'x - extracting screen.c (Text)'
  855. sed 's/^X//' << 'SHAR_EOF' > 'screen.c' &&
  856. X#ifndef lint
  857. Xstatic char Sccsid[] = "@(#)screen.c    3.2    DeltaDate 8/11/90    ExtrDate 10/6/90";
  858. X#endif
  859. X
  860. X/*    SCREEN.C    */
  861. X/*    This subroutine is used to format a screen and handle
  862. X**    input to it. It expects as input:
  863. X**        1. A pointer to the title of the screen
  864. X**        2. A pointer to an array of structures describing
  865. X**           each field.
  866. X**        3. An (optional) pointer to a footer line.
  867. X**        4. An (optional) pointer to an integer to contain
  868. X**           the field number in which the pointer was left.
  869. X**        5. A flag which if TRUE makes the screen display only.
  870. X**    It returns the number of fields modified.
  871. X**    The external character lastchar will return the last charater input.
  872. X**
  873. X**    The field definition structures contain:
  874. X**        1. A character pointer to the title of the field
  875. X**        2. The maximum length of the field
  876. X**        3. A pointer to the variable to hold the result
  877. X**        4. An (optional) pointer to the default value
  878. X**        5. An (optional) row for the title
  879. X**        6. An (optional) column for the title
  880. X**        7. An (optional) row for the data
  881. X**        8. An (optional) column for the data
  882. X**        9. An (optional) format for the data
  883. X**
  884. X**    It allows the user to enter:
  885. X**        1. CR   End of Input
  886. X**        2. ->   Move right
  887. X**        3. <-   Move left
  888. X**        4. TAB  Move to next field, wrap around to top
  889. X**        5. BACK-TAB Move to previous field, wrap to the bottom field
  890. X**        6. LINE-ERASE Erase to end of field
  891. X**        7. CHAR-INSERT Insert a blank and move everything right
  892. X**        8. CHAR-DELETE Delete a character and move everything left
  893. X**        9. DOWN-ARROW Same as TAB
  894. X**           10. UP-ARROW Same as BACK-TAB
  895. X**           11. F2    Same as CHAR-INSERT
  896. X**           12. F3    Same as CHAR-DELETE
  897. X**           13. F4    Same as LINE-ERASE
  898. X**           14. F5    Go to the first field on the next page of a
  899. X**            multi-page form
  900. X**           15. F6    Go to the previous page
  901. X*/
  902. X
  903. X#include "cardfile.h"
  904. X#include "stdio.h"
  905. X#include "ascii.h"
  906. X#include <ctype.h>
  907. X#include <signal.h>
  908. X#ifdef TERMCAP
  909. X#include <termio.h>
  910. X#define tparm(a, line, col)    tgoto(a, col, line)
  911. X#define    putp(a)        tputs(a, 12, mputc)
  912. X#else
  913. X#include <curses.h>
  914. X#include <term.h>
  915. X#endif
  916. X#ifdef BSD_TTY
  917. X#include <sgtty.h>
  918. X#endif
  919. X#ifdef BSD_SIG
  920. X#include <setjmp.h>
  921. Xjmp_buf    jbuf;
  922. X#endif
  923. X
  924. X#ifdef TERMCAP
  925. Xextern char *tgoto(), *getenv();
  926. Xextern char
  927. X    *clear_screen,
  928. X    *clr_eol,
  929. X    *enter_dim_mode,
  930. X    *enter_blink_mode,
  931. X    *exit_attribute_mode,
  932. X    *keypad_xmit,
  933. X    *keypad_local,
  934. X    *cursor_address,
  935. X    *cursor_left,
  936. X    *cursor_right;
  937. Xint    mputc();
  938. X#endif
  939. X
  940. X
  941. Xextern struct cchar    *cc_head;
  942. Xextern    char    func_label[];
  943. X
  944. Xchar        lastchar;
  945. X
  946. Xstatic  int    flen;
  947. Xstatic  char    *cp;
  948. Xstatic  int    changes;
  949. Xstatic    int    fmt_msg = FALSE;
  950. Xstatic  struct    SFdata {
  951. X        int    f_page;
  952. X        int    f_tline;
  953. X        int    f_tcol;
  954. X        char    *f_title;
  955. X        int    f_dline;
  956. X        int    f_dcol;
  957. X        char    *f_dfmt;
  958. X        int    f_length;
  959. X        char    *f_result;
  960. X        char    *f_dfault;
  961. X    } scr_fields[MAXFLDS+1];
  962. Xstatic    struct    SFdata    *fp, *first_field;
  963. Xstatic    int    page_num;
  964. Xstatic    int    read_only;    /* true if not to be modified */
  965. X
  966. XSIGRTN    ctl_timeout();
  967. Xstatic    int    timedout;
  968. X
  969. Xint
  970. Xscreen(first, vardata, last, left, ro)
  971. Xchar    *first, *last;
  972. Xstruct  Sdata   *vardata;
  973. Xint    *left;
  974. Xint    ro;
  975. X{
  976. X    int        inp;
  977. X    char    t_last[81];
  978. X    char    mbuf[81];
  979. X    register    struct    cchar *sp;
  980. X    struct    SFdata    *last_field;
  981. X
  982. X    read_only = ro;
  983. X#if DEBUG > 0
  984. X    fprintf(stderr,"screen: called first=%s\n",first);
  985. X#endif
  986. X    /*
  987. X     * Build the scr_fields table
  988. X     */
  989. X    scr_fields[0].f_page = 1;
  990. X    scr_fields[0].f_tline = 2;
  991. X    for (fp = scr_fields ; vardata->S_title != NULL ; ++vardata , ++fp) {
  992. X    if (vardata->S_Lrow != -1) {
  993. X        fp->f_tline = vardata->S_Lrow;
  994. X    }
  995. X    if (vardata->S_Lcol != -1) {
  996. X        fp->f_tcol = vardata->S_Lcol;
  997. X    } else {
  998. X        fp->f_tcol = 4;
  999. X    }
  1000. X    if (vardata->S_Drow != -1) {
  1001. X        fp->f_dline = vardata->S_Drow;
  1002. X    } else {
  1003. X        fp->f_dline = fp->f_tline;
  1004. X    }
  1005. X    if (vardata->S_Dcol != -1) {
  1006. X        fp->f_dcol = vardata->S_Dcol;
  1007. X    } else {
  1008. X        if (vardata->S_length > 1) {
  1009. X        fp->f_dcol = fp->f_tcol + strlen(vardata->S_title) + 6;
  1010. X        if (vardata->S_length > 99)
  1011. X            fp->f_dcol += 2;
  1012. X        else if (vardata->S_length > 9)
  1013. X            fp->f_dcol += 1;
  1014. X        } else {
  1015. X        fp->f_dcol = fp->f_tcol + strlen(vardata->S_title) + 3;
  1016. X        }
  1017. X    }
  1018. X    fp->f_title = vardata->S_title;
  1019. X    fp->f_length = vardata->S_length;
  1020. X    fp->f_result = vardata->S_result;
  1021. X    fp->f_dfault = vardata->S_dfault;
  1022. X    fp->f_dfmt = vardata->S_Dfmt;
  1023. X    /* check if too much for this screen */
  1024. X    if ( (fp->f_tline + (fp->f_dcol + fp->f_length + SWIDTH-1)/SWIDTH)
  1025. X       > SLENGTH - 4) {
  1026. X        (fp+1)->f_page = fp->f_page + 1;
  1027. X        (fp+1)->f_tline = 2;
  1028. X    } else {
  1029. X        (fp+1)->f_page = fp->f_page;
  1030. X        (fp+1)->f_tline = fp->f_tline + 1
  1031. X        + (fp->f_dcol + fp->f_length + SWIDTH-1)/SWIDTH;
  1032. X    }
  1033. X    }
  1034. X    fp->f_page = fp->f_tline = 0;
  1035. X#if DEBUG > 0
  1036. X    fprintf(stderr, "%-4s  %-4s  %-10.10s %-5s  %-4s\n",
  1037. X    "", "", "", "data", "data");
  1038. X    fprintf(stderr, "%-4s  %-4s  %-10.10s %-5s  %-4s\n",
  1039. X    "page", "line", "title", "start", "size");
  1040. X    for (fp = scr_fields ; fp->f_page != 0 ; ++fp) {
  1041. X    fprintf(stderr, "%4d  %4d  %-10.10s %5d %4d\n",
  1042. X        fp->f_page, fp->f_tline, fp->f_title, fp->f_dcol, fp->f_length);
  1043. X    }
  1044. X#endif
  1045. X    /*
  1046. X     *    Format the screen
  1047. X     */
  1048. X    changes = 0;
  1049. X    noecho();
  1050. X    /* Loop for all pages */
  1051. X    for (page_num = 1 , first_field = scr_fields
  1052. X     ; first_field->f_page != 0 ; ) {
  1053. X#if DEBUG > 1
  1054. X    fprintf(stderr,"screen: outer loop, page_num=%d\n",page_num);
  1055. X#endif
  1056. X    putp(clear_screen);            /* clear screen */
  1057. X    putp(tparm(cursor_address, 0, 9));
  1058. X    fputs(first, stdout);            /* display title */
  1059. X    /* Loop for each field on 1 page */
  1060. X    for (fp = first_field ; fp->f_page == page_num ; ++fp) {
  1061. X#if DEBUG > 1
  1062. X        fprintf(stderr,"screen: inner loop, page_num=%d, line=%d\n",
  1063. X        page_num, fp->f_tline);
  1064. X#endif
  1065. X        putp(tparm(cursor_address, fp->f_tline, fp->f_tcol-1));
  1066. X        putp(enter_dim_mode);
  1067. X        if (fp->f_length > 1) {
  1068. X        putp(tparm(cursor_address, fp->f_tline, fp->f_tcol));
  1069. X        printf("%s(%d):", fp->f_title, fp->f_length);
  1070. X        } else {
  1071. X        putp(tparm(cursor_address, fp->f_tline, fp->f_tcol));
  1072. X        printf("%s:", fp->f_title);
  1073. X        }
  1074. X        putp(exit_attribute_mode);
  1075. X        if (fp->f_dfault != 0) {
  1076. X        strcpy(fp->f_result, fp->f_dfault);
  1077. X        putp(tparm(cursor_address, fp->f_dline, fp->f_dcol));
  1078. X        fputs(fp->f_dfault, stdout);
  1079. X        flen = strlen(fp->f_dfault);
  1080. X        } else {
  1081. X        flen = 0;
  1082. X        fp->f_result[0] = '\0';
  1083. X        }
  1084. X        putchar('\n');
  1085. X        for (flen=strlen(fp->f_result); flen <= fp->f_length; flen++)
  1086. X        fp->f_result[flen] = '\0';
  1087. X    }
  1088. X    /* check if too much for this screen */
  1089. X    if (fp->f_page != 0) {
  1090. X        sprintf(t_last, "%-64s[CONT]", last?last:"");
  1091. X    } else {
  1092. X        strcpy(t_last, last?last:"");
  1093. X    }
  1094. X    /* Write instructions if any */
  1095. X    if (*t_last != '\0') {
  1096. X        putp(tparm(cursor_address, MSGLINE, 9));
  1097. X        fputs(t_last, stdout);
  1098. X    }
  1099. X    putp(tparm(cursor_address, SLENGTH-1, 0));
  1100. X    fputs(func_label, stdout);
  1101. X    fp = first_field;
  1102. X    cp = fp->f_result;
  1103. X    resetcursor();
  1104. X    flen = fp->f_length;
  1105. X    
  1106. X    /*
  1107. X     *    Process the user input
  1108. X     */
  1109. X    while ((inp = rawgetchar())) {
  1110. X        lastchar = inp;
  1111. X        if (inp == '\n' || inp == '\r') {
  1112. X        /* check format first */
  1113. X        if (! read_only && fp->f_dfmt[0] && fp->f_result[0]) {
  1114. X            if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
  1115. X            fmt_msg = TRUE;
  1116. X            sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
  1117. X            msg(mbuf);
  1118. X            rawputchar(BEL);
  1119. X            cp = fp->f_result;
  1120. X            flen = fp->f_length;
  1121. X            resetcursor();
  1122. X            continue;
  1123. X            } else {
  1124. X            if (fmt_msg) {
  1125. X                msg("");
  1126. X                fmt_msg = FALSE;
  1127. X            }
  1128. X            }
  1129. X
  1130. X        }
  1131. X        if (fmt_msg) {
  1132. X            msg("");
  1133. X            fmt_msg = FALSE;
  1134. X        }
  1135. X        break;
  1136. X        }
  1137. X        /*
  1138. X         * Check for control key sequence
  1139. X         */
  1140. X        timedout = FALSE;
  1141. X        signal(SIGALRM, ctl_timeout);
  1142. X        alarm(1);
  1143. X        sp = cc_head;
  1144. X        while (sp) {
  1145. X        if (inp == sp->ch) {
  1146. X            inp = process_ctl(sp);
  1147. X            break;
  1148. X        }
  1149. X        sp = sp->alt;
  1150. X        }
  1151. X        alarm(0);
  1152. X        signal(SIGALRM, SIG_DFL);
  1153. X        if (sp != NULL) {        /* control character match found */
  1154. X        if (inp == -1)    /* page switch */
  1155. X            break;
  1156. X        if (read_only && timedout)
  1157. X            return(0);
  1158. X        continue;
  1159. X        }
  1160. X        if (read_only) {
  1161. X        return(0);
  1162. X        }
  1163. X        /*
  1164. X         * Process a normal character
  1165. X         */
  1166. X        /* Control characters are illegal (also catches illegal controls) */
  1167. X        if (! isascii(inp) || iscntrl(inp)) {
  1168. X        rawputchar(BEL);
  1169. X        continue;
  1170. X        }
  1171. X        rawputchar(inp);        /* echo character */
  1172. X        *cp++ = inp;
  1173. X        ++changes;
  1174. X        if (--flen <= 0)        /* reached end of field */
  1175. X        nextfield(scr_fields);
  1176. X    }   /* End of INPut Loop */
  1177. X#if DEBUG > 0
  1178. X    fprintf(stderr,"screen: end of outer loop, inp=%d\n",inp);
  1179. X#endif
  1180. X    last_field = fp;
  1181. X    if (inp == '\n' || inp == '\r')
  1182. X        break;
  1183. X    }
  1184. X
  1185. X    echo();
  1186. X    if (left != NULL)
  1187. X    *left = last_field - scr_fields;
  1188. X#ifdef DEBUG
  1189. X    fprintf(stderr,"screen exit, left=%d, changes=%d\n",
  1190. X        (left ? *left : -1), changes);
  1191. X#endif
  1192. X    return changes;
  1193. X}
  1194. X
  1195. X
  1196. Xint
  1197. Xprocess_ctl(ccp)
  1198. Xstruct cchar *ccp;
  1199. X{
  1200. X    int        ch;
  1201. X
  1202. X    /* check for end of control sequence */
  1203. X    if (ccp->action) {
  1204. X    return((*ccp->action)(scr_fields));
  1205. X    }
  1206. X#ifdef BSD_SIG
  1207. X    if (setjmp(jbuf) != 0) {
  1208. X    /* return from interupt */
  1209. X    return(0);
  1210. X    }
  1211. X#endif
  1212. X    if ((ch = rawgetchar()) == EOF) {
  1213. X    if (! read_only)
  1214. X        rawputchar(BEL);
  1215. X    return(0);
  1216. X    }
  1217. X    lastchar = ch;
  1218. X    ccp = ccp->next;
  1219. X    while (ccp) {
  1220. X    if (ch == ccp->ch)
  1221. X        return(process_ctl(ccp));
  1222. X    ccp = ccp->alt;
  1223. X    }
  1224. X    rawputchar(BEL);
  1225. X    return(0);        /* illegal sequence */
  1226. X}
  1227. X
  1228. XSIGRTN
  1229. Xctl_timeout()
  1230. X{
  1231. X    timedout = TRUE;
  1232. X#ifdef BSD_SIG
  1233. X    longjmp(jbuf, 1);
  1234. X#endif
  1235. X    return;
  1236. X}
  1237. X
  1238. X/*
  1239. X *    These are the action routines to manage the fields on the screen.
  1240. X * Each routine is called from the getchar loop above when an action key
  1241. X * is read. The routine is passed the screen data structure.
  1242. X *
  1243. X * Globally they use
  1244. X * fp        pointer to the current entry in the fields table (SFtable)
  1245. X * cp        character position, i.e., character in which next input
  1246. X *        is to be placed
  1247. X * flen        length of input field
  1248. X * changes    flag if screen has been modified
  1249. X * page_num    the page of fields displayed
  1250. X * first_field    the first field displayed on the screen
  1251. X */
  1252. X
  1253. X/*ARGSUSED*/
  1254. Xnextpage(field_tbl)
  1255. Xstruct    SFdata    field_tbl[];
  1256. X{
  1257. X    char    mbuf[81];
  1258. X
  1259. X    /* see if format needs to be checked */
  1260. X    if (fp->f_dfmt[0] && fp->f_result[0]) {
  1261. X    if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
  1262. X        fmt_msg = TRUE;
  1263. X        sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
  1264. X        msg(mbuf);
  1265. X        rawputchar(BEL);
  1266. X        cp = fp->f_result;
  1267. X        flen = fp->f_length;
  1268. X        resetcursor();
  1269. X        return(0);
  1270. X    } else {
  1271. X        if (fmt_msg) {
  1272. X        msg("");
  1273. X        fmt_msg = FALSE;
  1274. X        }
  1275. X    }
  1276. X    }
  1277. X    if (fmt_msg) {
  1278. X    msg("");
  1279. X    fmt_msg = FALSE;
  1280. X    }
  1281. X
  1282. X    page_num++;
  1283. X    for (first_field = field_tbl ;
  1284. X     first_field->f_page != page_num && first_field->f_page != 0 ;
  1285. X     ++first_field)
  1286. X    ;
  1287. X    if (first_field->f_page == 0) {    /* wrap around */
  1288. X    page_num = 1;
  1289. X    first_field = field_tbl;
  1290. X    }
  1291. X#if DEBUG > 0
  1292. X    fprintf(stderr, "nextpage: page=%d, first_field=%d\n",
  1293. X    page_num, first_field-field_tbl);
  1294. X#endif
  1295. X    return(-1);        /* force termination of input loop */
  1296. X}
  1297. X
  1298. X
  1299. Xprevpage(field_tbl)
  1300. Xstruct    SFdata    field_tbl[];
  1301. X{
  1302. X    register struct    SFdata    *t_fp;
  1303. X    char    mbuf[81];
  1304. X
  1305. X    /* see if format needs to be checked */
  1306. X    if (fp->f_dfmt[0] && fp->f_result[0]) {
  1307. X    if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
  1308. X        fmt_msg = TRUE;
  1309. X        sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
  1310. X        msg(mbuf);
  1311. X        rawputchar(BEL);
  1312. X        cp = fp->f_result;
  1313. X        flen = fp->f_length;
  1314. X        resetcursor();
  1315. X        return(0);
  1316. X    } else {
  1317. X        if (fmt_msg) {
  1318. X        msg("");
  1319. X        fmt_msg = FALSE;
  1320. X        }
  1321. X    }
  1322. X    }
  1323. X    if (fmt_msg) {
  1324. X    msg("");
  1325. X    fmt_msg = FALSE;
  1326. X    }
  1327. X
  1328. X    if (--page_num < 1) {    /* wrap around */
  1329. X    for (t_fp = field_tbl ; (t_fp+1)->f_page != 0 ; ++t_fp)
  1330. X        ;
  1331. X    page_num = t_fp->f_page;
  1332. X    }
  1333. X    for (first_field = field_tbl ;
  1334. X     first_field->f_page != page_num && first_field->f_page != 0 ;
  1335. X     ++first_field)
  1336. X    ;
  1337. X#if DEBUG > 0
  1338. X    fprintf(stderr, "prevpage: page=%d, first_field=%d\n",
  1339. X    page_num, first_field-field_tbl);
  1340. X#endif
  1341. X    return(-1);        /* force termination of input loop */
  1342. X}
  1343. X
  1344. X
  1345. X/*ARGSUSED*/
  1346. Xnextfield(dummy)
  1347. Xstruct    SFdata    dummy[];
  1348. X{
  1349. X    register int page;
  1350. X    char    mbuf[81];
  1351. X
  1352. X    /* see if format needs to be checked */
  1353. X    if (fp->f_dfmt[0] && fp->f_result[0]) {
  1354. X    if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
  1355. X        fmt_msg = TRUE;
  1356. X        sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
  1357. X        msg(mbuf);
  1358. X        rawputchar(BEL);
  1359. X        cp = fp->f_result;
  1360. X        flen = fp->f_length;
  1361. X        resetcursor();
  1362. X        return(0);
  1363. X    } else {
  1364. X        if (fmt_msg) {
  1365. X        msg("");
  1366. X        fmt_msg = FALSE;
  1367. X        }
  1368. X    }
  1369. X    }
  1370. X    if (fmt_msg) {
  1371. X    msg("");
  1372. X    fmt_msg = FALSE;
  1373. X    }
  1374. X
  1375. X    page  = fp->f_page;
  1376. X    ++fp;
  1377. X    if (fp->f_page != page) {        /* wrap-around */
  1378. X    fp = first_field;
  1379. X    }
  1380. X    cp = fp->f_result;
  1381. X    flen = fp->f_length;
  1382. X    resetcursor();
  1383. X    return(0);
  1384. X}
  1385. X
  1386. X
  1387. X/*ARGSUSED*/
  1388. Xprevfield(dummy)
  1389. Xstruct    SFdata    dummy[];
  1390. X{
  1391. X    register int page;
  1392. X    char    mbuf[81];
  1393. X
  1394. X    /* see if format needs to be checked */
  1395. X    if (fp->f_dfmt[0] && fp->f_result[0]) {
  1396. X    if (fmt_chk(fp->f_result, fp->f_dfmt) != 0) {
  1397. X        fmt_msg = TRUE;
  1398. X        sprintf(mbuf, "Invalid format, should be %.40s", fp->f_dfmt);
  1399. X        msg(mbuf);
  1400. X        rawputchar(BEL);
  1401. X        cp = fp->f_result;
  1402. X        flen = fp->f_length;
  1403. X        resetcursor();
  1404. X        return(0);
  1405. X    } else {
  1406. X        if (fmt_msg) {
  1407. X        msg("");
  1408. X        fmt_msg = FALSE;
  1409. X        }
  1410. X    }
  1411. X    }
  1412. X    if (fmt_msg) {
  1413. X    msg("");
  1414. X    fmt_msg = FALSE;
  1415. X    }
  1416. X
  1417. X    if (cp == fp->f_result) {   /* at beginning of field */
  1418. X    if (fp == first_field) {    /* wrap around */
  1419. X        page = fp->f_page;
  1420. X        while ((++fp)->f_page == page)
  1421. X        ;
  1422. X    }
  1423. X    --fp;
  1424. X    }
  1425. X    cp = fp->f_result;
  1426. X    flen = fp->f_length;
  1427. X    resetcursor();
  1428. X    return(0);
  1429. X}
  1430. X
  1431. X
  1432. Xgoright(field_tbl)
  1433. Xstruct    SFdata    field_tbl[];
  1434. X{
  1435. X    register int    pos;
  1436. X
  1437. X    if (--flen <= 0)
  1438. X    nextfield(field_tbl);
  1439. X    if (*cp == '\0')
  1440. X    *cp = ' ';
  1441. X    cp++;
  1442. X    pos = cp - fp->f_result + fp->f_dcol;
  1443. X    if (pos % SWIDTH == 0) {
  1444. X    resetcursor();
  1445. X    } else {
  1446. X    putp(cursor_right);
  1447. X    }
  1448. X    return(0);
  1449. X}
  1450. X
  1451. X
  1452. Xgoleft(field_tbl)
  1453. Xstruct    SFdata    field_tbl[];
  1454. X{
  1455. X    register int    pos;
  1456. X
  1457. X    if (++flen > fp->f_length) {
  1458. X    prevfield(field_tbl);
  1459. X    } else {
  1460. X    --cp;
  1461. X    pos = cp - fp->f_result + fp->f_dcol;
  1462. X    if (pos % SWIDTH == SWIDTH - 1) {
  1463. X        resetcursor();
  1464. X    } else {
  1465. X        putp(cursor_left);
  1466. X    }
  1467. X    }
  1468. X    return(0);
  1469. X}
  1470. X
  1471. X
  1472. X/*ARGSUSED*/
  1473. Xferase(dummy)
  1474. Xstruct  Sdata   *dummy;
  1475. X{
  1476. X    register char    *cpt;
  1477. X    register int    flent;
  1478. X    
  1479. X    cpt = cp;
  1480. X    flent = flen;
  1481. X    while (flent-- > 0) {
  1482. X    *(cpt++) = '\0';
  1483. X    rawputchar(' ');
  1484. X    }
  1485. X    resetcursor();
  1486. X    ++changes;
  1487. X    return(0);
  1488. X}
  1489. X
  1490. X
  1491. X/*ARGSUSED*/
  1492. Xdelchar(dummy)
  1493. Xstruct  Sdata   *dummy;
  1494. X{
  1495. X    strcpy(cp, cp+1);
  1496. X    fputs(cp, stdout);
  1497. X    rawputchar(' ');
  1498. X    resetcursor();
  1499. X    ++changes;
  1500. X    return(0);
  1501. X}
  1502. X
  1503. X
  1504. X/*ARGSUSED*/
  1505. Xinschar(dummy)
  1506. Xstruct  Sdata   *dummy;
  1507. X{
  1508. X    mvright(cp+1, cp);
  1509. X    *cp = ' ';
  1510. X    fputs(cp, stdout);
  1511. X    resetcursor();
  1512. X    ++changes;
  1513. X    return(0);
  1514. X}
  1515. X
  1516. X
  1517. Xmvright(d, s)
  1518. Xchar    *d, *s;
  1519. X{
  1520. X    register int    slen;
  1521. X    
  1522. X    slen = strlen(s);
  1523. X    while (slen-- >= 0)
  1524. X    *(d+slen) = *(s+slen);
  1525. X    return(0);
  1526. X}
  1527. X
  1528. X
  1529. Xresetcursor()
  1530. X{
  1531. X    register int    flent;
  1532. X
  1533. X    flent = cp - fp->f_result + fp->f_dcol;
  1534. X    putp(tparm(cursor_address, fp->f_dline + flent/SWIDTH, flent%SWIDTH));
  1535. X}
  1536. X
  1537. X#ifdef BSD_TTY
  1538. Xstatic struct    sgttyb    instty, outstty;
  1539. X#else    /* SYSV_TTY */
  1540. Xstatic struct    termio    instty, outstty;
  1541. X#endif
  1542. X
  1543. X
  1544. Xvoid
  1545. Xsetupscr()
  1546. X{
  1547. X    
  1548. X    setbuf(stdout, NULL);
  1549. X    setbuf(stdin, NULL);
  1550. X#ifdef BSD_TTY
  1551. X    ioctl(0, TIOCGETP, &outstty);
  1552. X    instty.sg_ispeed = outstty.sg_ispeed;
  1553. X    instty.sg_ospeed = outstty.sg_ospeed;
  1554. X    instty.sg_erase = outstty.sg_erase;
  1555. X    instty.sg_kill = outstty.sg_kill;
  1556. X    instty.sg_flags = RAW;
  1557. X    ioctl(0, TIOCSETP, &instty);
  1558. X#else    /* SYSV_TTY */
  1559. X    ioctl(0, TCGETA, &outstty);
  1560. X    instty.c_iflag = outstty.c_iflag;
  1561. X    instty.c_oflag = outstty.c_oflag;
  1562. X    instty.c_cflag = outstty.c_cflag;
  1563. X    instty.c_lflag = 0;        /* turn off icanon, echo */
  1564. X    instty.c_line = outstty.c_line;
  1565. X    instty.c_cc[VINTR] = outstty.c_cc[VINTR];
  1566. X    instty.c_cc[VQUIT] = outstty.c_cc[VQUIT];
  1567. X    instty.c_cc[VERASE] = outstty.c_cc[VERASE];
  1568. X    instty.c_cc[VKILL] = outstty.c_cc[VKILL];
  1569. X    instty.c_cc[VMIN] = 1;
  1570. X    instty.c_cc[VTIME] = 0;
  1571. X    instty.c_cc[6] = outstty.c_cc[6];
  1572. X    instty.c_cc[7] = outstty.c_cc[7];
  1573. X    ioctl(0, TCSETAW, &instty);
  1574. X#endif
  1575. X#ifdef TERMINFO
  1576. X    setupterm((char*)0, 1, (int*)0);
  1577. X#else
  1578. X    setterm(getenv("TERM"));
  1579. X#endif
  1580. X    setupkeys();
  1581. X    putp(keypad_xmit);
  1582. X}
  1583. X
  1584. XSIGRTN
  1585. Xgetout()
  1586. X{
  1587. X
  1588. X    putp(keypad_local);
  1589. X    putp(clear_screen);
  1590. X#ifdef BSD_TTY
  1591. X    ioctl(0, TIOCSETP, &outstty);
  1592. X#else    /* SYSV_TTY */
  1593. X    ioctl(0, TCSETAW, &outstty);
  1594. X#endif
  1595. X    exit(0);
  1596. X}
  1597. X
  1598. SHAR_EOF
  1599. true || echo 'restore of screen.c failed'
  1600. # ============= setupkeys.c ==============
  1601. echo 'x - extracting setupkeys.c (Text)'
  1602. sed 's/^X//' << 'SHAR_EOF' > 'setupkeys.c' &&
  1603. X#ifndef lint
  1604. Xstatic char Sccsid[] = "@(#)setupkeys.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  1605. X#endif
  1606. X
  1607. X/*    SETUPKEYS.C         */
  1608. X/*    This module sets up all terminal specific key sequences.
  1609. X**    It sets up the a linked list that translates function keys to
  1610. X**    actions and sets up the label for the function keys.
  1611. X**
  1612. X**  It requires definitions of
  1613. X**    key_right    move cursor right
  1614. X**    key_left    move cursor left
  1615. X**    key_backspace    "
  1616. X**    key_tab        move forward thru fields
  1617. X**    key_down    "
  1618. X**    key_btab    move backward thru fields
  1619. X**    key_up        "
  1620. X**    key_eol        clear to end of field
  1621. X**    key_dc        delete character under cursor
  1622. X**    key_ic        move characters from the cursor on one space right
  1623. X**    key_f2        same as key_ic
  1624. X**    key_f3        same as key_dc
  1625. X**    key_f4        same as key_eol
  1626. X**    key_f5        next page
  1627. X**    key_f6        previous page
  1628. X**/
  1629. X
  1630. X# include <curses.h>
  1631. X#ifndef TERMCAP
  1632. X# include <term.h>
  1633. X#endif
  1634. X#ifdef DEBUG
  1635. X#include <stdio.h>
  1636. X#endif
  1637. X#include "cardfile.h"
  1638. X
  1639. X/*
  1640. X** Indices into "keys" structure
  1641. X**/
  1642. X#define    k_BS    0
  1643. X#define    k_LEFT    1
  1644. X#define    k_RIGHT    2
  1645. X#define    k_EOL    3
  1646. X#define    k_DC    4
  1647. X#define    k_IC    5
  1648. X#define    k_TAB    6
  1649. X#define    k_UP    7
  1650. X#define    k_DOWN    8
  1651. X#define    k_F2    9
  1652. X#define    k_F3    10
  1653. X#define    k_F4    11
  1654. X#define    k_F5    12
  1655. X#define    k_F6    13
  1656. X#define    k_BTAB    14
  1657. X
  1658. Xint    sfunct(), goright(), goleft(), nextfield(), prevfield(), ferase();
  1659. Xint    delchar(), inschar(), nextpage(), prevpage();
  1660. Xunsigned sleep();
  1661. Xchar    *malloc();
  1662. Xchar    *memset();
  1663. Xchar    *strstr();
  1664. X
  1665. X/* translation of terminfo/termcap names to action routines */
  1666. Xstruct    keys    {
  1667. X    char    *terminfo_name;
  1668. X    char    *string;
  1669. X    int    (*func)();
  1670. X};
  1671. Xstatic struct keys keys[20] = {
  1672. X    {"key_backspace", 0, goleft},
  1673. X    {"key_left",      0, goleft},
  1674. X    {"key_right",     0, goright},
  1675. X    {"key_eol",          0, ferase},
  1676. X    {"key_dc",          0, delchar},
  1677. X    {"key_ic",          0, inschar},
  1678. X    {"tab",          0, nextfield},
  1679. X    {"key_up",          0, prevfield},
  1680. X    {"key_down",      0, nextfield},
  1681. X    {"key_f2",          0, inschar},
  1682. X    {"key_f3",          0, delchar},
  1683. X    {"key_f4",          0, ferase},
  1684. X    {"key_f5",          0, nextpage},
  1685. X    {"key_f6",          0, prevpage},
  1686. X#ifdef key_btab
  1687. X    {"key_btab",      0, prevfield},
  1688. X#endif
  1689. X    { 0, 0, 0}
  1690. X};
  1691. X
  1692. X#ifdef TERMCAP
  1693. Xchar    *clear_screen,
  1694. X    *clr_eol,
  1695. X    *enter_dim_mode,
  1696. X    *enter_blink_mode,
  1697. X    *exit_attribute_mode,
  1698. X    *keypad_xmit,
  1699. X    *keypad_local,
  1700. X    *cursor_address,
  1701. X    *cursor_left,
  1702. X    *cursor_right;
  1703. X#endif
  1704. X
  1705. Xstruct cchar *cc_head;
  1706. X
  1707. Xchar    func_label[256];
  1708. X
  1709. Xsetupkeys()
  1710. X{
  1711. X    register struct keys    *kp;
  1712. X    register char   *so_on, *so_off;
  1713. X    register char   *cp;
  1714. X    register struct cchar    *ccp;
  1715. X    int    slen;
  1716. X#ifdef TERMCAP
  1717. X    static    char    tc_buf[1024];
  1718. X    static    char    *tc_ptr = tc_buf;
  1719. X    static    char    tc_out[256];
  1720. X    static    char    *out_ptr = tc_out;
  1721. X    extern    char    *tgetstr(), *tgoto();
  1722. X    extern    char    *getenv();
  1723. X#endif
  1724. X
  1725. X#ifdef TERMCAP
  1726. X    if (tgetent(tc_buf, (cp = getenv("TERM"))) != 1) {
  1727. X    printf(stderr, "Unable to get terminal settings for %s\n",
  1728. X        (cp ? cp : "<NULL>"));
  1729. X    exit(1);
  1730. X    }
  1731. X    if ((keys[k_BS].string = tgetstr("kb", &out_ptr)) == 0) {
  1732. X    keys[k_BS].string = "\b";
  1733. X    }
  1734. X    if ((keys[k_LEFT].string = tgetstr("kl", &out_ptr)) == 0) {
  1735. X    keys[k_LEFT].string = "";
  1736. X    }
  1737. X    if ((keys[k_RIGHT].string = tgetstr("kr", &out_ptr)) == 0) {
  1738. X    keys[k_RIGHT].string = "";
  1739. X    }
  1740. X    if ((keys[k_EOL].string = tgetstr("kE", &out_ptr)) == 0) {
  1741. X    keys[k_EOL].string = "";
  1742. X    }
  1743. X    if ((keys[k_DC].string = tgetstr("kD", &out_ptr)) == 0) {
  1744. X    keys[k_DC].string = "";
  1745. X    }
  1746. X    if ((keys[k_IC].string = tgetstr("kI", &out_ptr)) == 0) {
  1747. X    keys[k_IC].string = "";
  1748. X    }
  1749. X    if ((keys[k_TAB].string = tgetstr("ta", &out_ptr)) == 0) {
  1750. X    keys[k_TAB].string = "\t";
  1751. X    }
  1752. X    if ((keys[k_UP].string = tgetstr("ku", &out_ptr)) == 0) {
  1753. X    keys[k_UP].string = "";
  1754. X    }
  1755. X    if ((keys[k_DOWN].string = tgetstr("kd", &out_ptr)) == 0) {
  1756. X    keys[k_DOWN].string = "";
  1757. X    }
  1758. X    if ((keys[k_F2].string = tgetstr("k2", &out_ptr)) == 0) {
  1759. X    keys[k_F2].string = "";
  1760. X    }
  1761. X    if ((keys[k_F3].string = tgetstr("k3", &out_ptr)) == 0) {
  1762. X    keys[k_F3].string = "";
  1763. X    }
  1764. X    if ((keys[k_F4].string = tgetstr("k4", &out_ptr)) == 0) {
  1765. X    keys[k_F4].string = "";
  1766. X    }
  1767. X    if ((keys[k_F5].string = tgetstr("k5", &out_ptr)) == 0) {
  1768. X    keys[k_F5].string = "";
  1769. X    }
  1770. X    if ((keys[k_F6].string = tgetstr("k6", &out_ptr)) == 0) {
  1771. X    keys[k_F6].string = "";
  1772. X    }
  1773. X    if ((keys[k_BTAB].string = tgetstr("kB", &out_ptr)) == 0) {
  1774. X    keys[k_BTAB].string = "";
  1775. X    }
  1776. X
  1777. X    if ((clear_screen = tgetstr("cl", &out_ptr)) == 0) {
  1778. X    clear_screen = "";
  1779. X    }
  1780. X    if ((cursor_address = tgetstr("cm", &out_ptr)) == 0) {
  1781. X    cursor_address = "";
  1782. X    }
  1783. X    if ((enter_dim_mode = tgetstr("mh", &out_ptr)) == 0) {
  1784. X    enter_dim_mode = "";
  1785. X    }
  1786. X    if ((exit_attribute_mode = tgetstr("me", &out_ptr)) == 0) {
  1787. X    exit_attribute_mode = "";
  1788. X    }
  1789. X    if ((cursor_right = tgetstr("nd", &out_ptr)) == 0) {
  1790. X    cursor_right = "";
  1791. X    }
  1792. X    if ((cursor_left = tgetstr("le", &out_ptr)) == 0) {
  1793. X    cursor_left = "\b";
  1794. X    }
  1795. X    if ((keypad_xmit = tgetstr("ks", &out_ptr)) == 0) {
  1796. X    keypad_xmit = "";
  1797. X    }
  1798. X    if ((keypad_local = tgetstr("ke", &out_ptr)) == 0) {
  1799. X    keypad_local = "";
  1800. X    }
  1801. X    if ((clr_eol = tgetstr("ce", &out_ptr)) == 0) {
  1802. X    clr_eol = "";
  1803. X    }
  1804. X    if ((enter_blink_mode = tgetstr("mb", &out_ptr)) == 0) {
  1805. X    if ((enter_blink_mode = tgetstr("so", &out_ptr)) == 0)
  1806. X        enter_blink_mode = "";
  1807. X    }
  1808. X#else    /* TERMCAP */
  1809. X    setupterm((char*)0, 1, (int*)0);
  1810. X    keys[k_BS].string = key_backspace;
  1811. X    keys[k_LEFT].string = key_left;
  1812. X    keys[k_RIGHT].string = key_right;
  1813. X    keys[k_EOL].string = key_eol;
  1814. X    keys[k_DC].string = key_dc;
  1815. X    keys[k_IC].string = key_ic;
  1816. X    keys[k_TAB].string = tab;
  1817. X    keys[k_UP].string = key_up;
  1818. X    keys[k_DOWN].string = key_down;
  1819. X    keys[k_F2].string = key_f2;
  1820. X    keys[k_F3].string = key_f3;
  1821. X    keys[k_F4].string = key_f4;
  1822. X    keys[k_F5].string = key_f5;
  1823. X    keys[k_F6].string = key_f6;
  1824. X# ifdef key_btab
  1825. X    keys[k_BTAB].string = key_btab;
  1826. X# endif
  1827. X#endif    /* TERMCAP */
  1828. X
  1829. X/*
  1830. X * Set up function key label string
  1831. X */
  1832. X#ifdef TERMCAP
  1833. X    so_on = tgetstr("mr", &out_ptr);
  1834. X    so_off = tgetstr("me", &out_ptr);
  1835. X    if (so_on == 0 || strlen(so_on) == 0) {
  1836. X    so_on = tgetstr("se", &out_ptr);
  1837. X    so_off = tgetstr("so", &out_ptr);
  1838. X    }
  1839. X#else    /* TERMCAP */
  1840. X    so_on = enter_reverse_mode;
  1841. X    so_off = exit_attribute_mode;
  1842. X    if (so_on == 0 || strlen(so_on) == 0) {
  1843. X    so_on = enter_standout_mode;
  1844. X    so_off = exit_standout_mode;
  1845. X    }
  1846. X#endif    /* TERMCAP */
  1847. X    sprintf(func_label, "%s%8s%s %s%8s%s %s%8s%s %s%8s%s         ",
  1848. X    so_on, "", so_off,
  1849. X    so_on, (keys[k_F2].string[0]?"insert ":""), so_off,
  1850. X    so_on, (keys[k_F3].string[0]?"delete ":""), so_off,
  1851. X    so_on, (keys[k_F4].string[0]?"clr fld ":""), so_off);
  1852. X    sprintf(func_label+strlen(func_label), "%s%8s%s %s%8s%s %s%8s%s %s%8s%s",
  1853. X    so_on, (keys[k_F5].string[0]?"next pg":""), so_off,
  1854. X    so_on, (keys[k_F6].string[0]?"prev pg":""), so_off,
  1855. X    so_on, "", so_off,
  1856. X    so_on, "", so_off);
  1857. X
  1858. X/*
  1859. X** Set defaults for some keys
  1860. X**/
  1861. X    if (keys[k_BS].string == 0 || strlen(keys[k_BS].string) == 0)
  1862. X    keys[k_BS].string = "\b";
  1863. X    if (keys[k_TAB].string == 0 || strlen(keys[k_TAB].string) == 0)
  1864. X    keys[k_TAB].string = "\t";
  1865. X
  1866. X    cc_head = (struct cchar*)malloc(sizeof(struct cchar));
  1867. X    memset(cc_head, '\0', sizeof(struct cchar));
  1868. X
  1869. X    for (kp = keys; kp->terminfo_name; ++kp) {
  1870. X#ifdef DEBUG
  1871. X    fprintf(stderr, "Capname=%s,string='", kp->terminfo_name);
  1872. X    for (cp=kp->string ;  cp != 0 && *cp ; cp++)
  1873. X        fputs(unctrl(*cp), stderr);
  1874. X    fprintf(stderr,"'\n");
  1875. X#endif
  1876. X    if (kp->string == 0 || strlen(kp->string) == 0) {
  1877. X#ifdef DEBUG
  1878. X        fprintf(stderr, "Control sequence for \"%s\" doesn't exist\n",
  1879. X        kp->terminfo_name);
  1880. X#endif
  1881. X        continue;
  1882. X    }
  1883. X    /*
  1884. X     * Throw away pad string '$<nn>'
  1885. X     */
  1886. X    if ((cp = strstr(kp->string, "$<")) != NULL) {
  1887. X        /* num of chars to delete */
  1888. X        slen = strchr(cp, '>') - cp + 1;
  1889. X        if (slen > 0) {
  1890. X        strcpy(cp, cp+slen);
  1891. X        }
  1892. X    }
  1893. X
  1894. X    for (cp = kp->string, ccp = cc_head; *cp; ) {
  1895. X        if (ccp->ch == '\0')
  1896. X        ccp->ch = *cp;
  1897. X        if (ccp->ch == *cp) {
  1898. X        if (*(cp+1) == '\0') {    /* end of string, add action */
  1899. X            if (ccp->action != NULL) {
  1900. X            fprintf(stderr, "Control string conflict\n");
  1901. X            break;
  1902. X            } else {    /* add it */
  1903. X            ccp->action = kp->func;
  1904. X            break;
  1905. X            }
  1906. X        }
  1907. X        /* not end of string */
  1908. X        if (ccp->next == NULL) {
  1909. X            ccp->next = (struct cchar*)malloc(sizeof(struct cchar));
  1910. X            memset(ccp->next, '\0', sizeof(struct cchar));
  1911. X        }
  1912. X        ccp = ccp->next;
  1913. X        ++cp;
  1914. X        continue;
  1915. X        }
  1916. X        if (ccp->alt != NULL) {
  1917. X        ccp = ccp->alt;
  1918. X        continue;
  1919. X        }
  1920. X        /* allocate new alternate */
  1921. X        ccp->alt = (struct cchar*)malloc(sizeof(struct cchar));
  1922. X        memset(ccp->alt, '\0', sizeof(struct cchar));
  1923. X        ccp = ccp->alt;
  1924. X    }
  1925. X
  1926. X#if DEBUG > 1
  1927. X    dumptables(cc_head);
  1928. X#endif
  1929. X    }
  1930. X#if DEBUG == 1
  1931. X    dumptables(cc_head);
  1932. X    dumpcmd();
  1933. X#endif
  1934. X}
  1935. X
  1936. X
  1937. X/*    strstr        String version of strchr            */
  1938. X/*            Return pointer to 1st occurance of s2 in s1    */
  1939. X/*            Return NULL if not found            */
  1940. Xchar
  1941. X*strstr(s1, s2)
  1942. Xregister char *s1, *s2;
  1943. X{
  1944. X    register int    len;
  1945. X
  1946. X    len = strlen(s2);
  1947. X    while (*s1)
  1948. X    {
  1949. X        if (strncmp(s1, s2, len) == 0)
  1950. X            return(s1);
  1951. X        else
  1952. X            ++s1;
  1953. X    }
  1954. X    return(NULL);
  1955. X}
  1956. X
  1957. X
  1958. X#ifdef DEBUG
  1959. Xstatic
  1960. Xdumptables(head)
  1961. Xstruct cchar    *head;
  1962. X{
  1963. X    dtable(head);
  1964. X    if (head->alt)
  1965. X    dumptables(head->alt);
  1966. X    if (head->next)
  1967. X    dumptables(head->next);
  1968. X}
  1969. X
  1970. X
  1971. Xstatic
  1972. Xdtable(ccp)
  1973. Xregister struct    cchar    *ccp;
  1974. X{
  1975. X
  1976. X    fprintf(stderr, "%d:\tch='%s'\n", ccp-cc_head+1, unctrl(ccp->ch));
  1977. X    fprintf(stderr, "\tnext=%d", ccp->next?ccp->next-cc_head+1:0);
  1978. X    fprintf(stderr, "\talt=%d", ccp->alt?ccp->alt-cc_head+1:0);
  1979. X    if (ccp->action == goright) {
  1980. X    fprintf(stderr, "\taction=goright\n");
  1981. X    } else if (ccp->action == goleft) {
  1982. X    fprintf(stderr, "\taction=goleft\n");
  1983. X    } else if (ccp->action == nextfield) {
  1984. X    fprintf(stderr, "\taction=nfield\n");
  1985. X    } else if (ccp->action == prevfield) {
  1986. X    fprintf(stderr, "\taction=pfield\n");
  1987. X    } else if (ccp->action == ferase) {
  1988. X    fprintf(stderr, "\taction=ferase\n");
  1989. X    } else if (ccp->action == delchar) {
  1990. X    fprintf(stderr, "\taction=delchar\n");
  1991. X    } else if (ccp->action == inschar) {
  1992. X    fprintf(stderr, "\taction=inschar\n");
  1993. X    } else if (ccp->action == nextpage) {
  1994. X    fprintf(stderr, "\taction=nextpage\n");
  1995. X    } else if (ccp->action == prevpage) {
  1996. X    fprintf(stderr, "\taction=prevpage\n");
  1997. X    } else {
  1998. X    fprintf(stderr, "\n");
  1999. X    }
  2000. X}
  2001. X
  2002. Xstatic
  2003. Xdumpcmd()
  2004. X{
  2005. X
  2006. X    fprintf(stderr, "clear_screen='");
  2007. X    putctlstr(clear_screen);
  2008. X    fprintf(stderr,"'\n");
  2009. X    fprintf(stderr, "cursor_address='");
  2010. X    putctlstr(cursor_address);
  2011. X    fprintf(stderr,"'\n");
  2012. X    fprintf(stderr, "enter_dim_mode='");
  2013. X    putctlstr(enter_dim_mode);
  2014. X    fprintf(stderr,"'\n");
  2015. X    fprintf(stderr, "exit_attribute_mode='");
  2016. X    putctlstr(exit_attribute_mode);
  2017. X    fprintf(stderr,"'\n");
  2018. X    fprintf(stderr, "cursor_right='");
  2019. X    putctlstr(cursor_right);
  2020. X    fprintf(stderr,"'\n");
  2021. X    fprintf(stderr, "cursor_left='");
  2022. X    putctlstr(cursor_left);
  2023. X    fprintf(stderr,"'\n");
  2024. X    fprintf(stderr, "keypad_xmit='");
  2025. X    putctlstr(keypad_xmit);
  2026. X    fprintf(stderr,"'\n");
  2027. X    fprintf(stderr, "keypad_local='");
  2028. X    putctlstr(keypad_local);
  2029. X    fprintf(stderr,"'\n");
  2030. X    fprintf(stderr, "clr_eol='");
  2031. X    putctlstr(clr_eol);
  2032. X    fprintf(stderr,"'\n");
  2033. X    fprintf(stderr, "enter_blink_mode='");
  2034. X    putctlstr(enter_blink_mode);
  2035. X    fprintf(stderr,"'\n");
  2036. X}
  2037. X
  2038. X
  2039. Xstatic
  2040. Xputctlstr(str)
  2041. Xregister char    *str;
  2042. X{
  2043. X
  2044. X    for ( ;  str != 0 && *str ; str++)
  2045. X    fputs(unctrl(*str), stderr);
  2046. X}
  2047. X#endif
  2048. SHAR_EOF
  2049. true || echo 'restore of setupkeys.c failed'
  2050. # ============= updak.c ==============
  2051. echo 'x - extracting updak.c (Text)'
  2052. sed 's/^X//' << 'SHAR_EOF' > 'updak.c' &&
  2053. X#ifndef lint
  2054. Xstatic char Sccsid[] = "@(#)updak.c    3.1    DeltaDate 8/3/90    ExtrDate 10/6/90";
  2055. X#endif
  2056. X
  2057. X/*    UPDAK.C        */
  2058. X/*    These subroutines are used to update the alternate key files
  2059. X**    after the DB file has been changed.
  2060. X*/
  2061. X
  2062. X#include "stdio.h"
  2063. X#include "ascii.h"
  2064. X#include "cardfile.h"
  2065. X#include <ctype.h>
  2066. X
  2067. Xchar    *bufend;
  2068. X
  2069. Xbuildak(dbname, recd, addr, fp, buffer)
  2070. Xchar    *dbname, *recd;
  2071. Xlong    addr;
  2072. Xstruct    Fdata *fp;
  2073. Xchar    *buffer;
  2074. X{
  2075. X    char    *fld, *fld2;
  2076. X    char    temp[AKSIZE];
  2077. X    char    *getfield();
  2078. X
  2079. X    if (*buffer == '\0')    /* first time */
  2080. X    bufend = buffer;
  2081. X    for ( ; fp->F_title[0] != '\0' ; ++fp) {
  2082. X    if ((fld = getfield(recd, ":")) == 0)
  2083. X        continue;
  2084. X    recd += strlen(fld) + 1;
  2085. X    if (fp->F_key != 'N' && *fld != '\0') { /* AK record required */
  2086. X        while((fld2 = getfield(fld, fp->F_seps)) != NULL) {
  2087. X        fld = 0;
  2088. X        sprintf(temp, "%c:%s:%ld\n", fp->F_key, fld2, addr);
  2089. X        /* check if buffer full */
  2090. X        if (bufend+strlen(temp)+1 >= buffer+BUFSIZE) {
  2091. X            writeak(dbname, buffer);
  2092. X        }
  2093. X        strcpy(bufend, temp);
  2094. X        bufend += strlen(temp);
  2095. X        }
  2096. X    }
  2097. X    }
  2098. X}
  2099. X
  2100. X
  2101. Xwriteak(dbname, buffer)        /* sort the lines in buffer then merge */
  2102. Xchar    *dbname;        /* them in with the appropriate AK file*/
  2103. Xchar    *buffer;
  2104. X{
  2105. X    char    *line[400];
  2106. X    int     nlines, i;
  2107. X    char    fnum, akname[FNSIZE];
  2108. X    FILE    *akfile;
  2109. X    char    *strchr();
  2110. X    int        compar();
  2111. X    void    qsort();
  2112. X
  2113. X    nlines = 0;
  2114. X    bufend = buffer;        /* reset end of buffer pointer */
  2115. X    while(*buffer != '\0') {    /* Build file to be sorted */
  2116. X    line[nlines++] = buffer;
  2117. X    buffer = strchr(buffer, '\n') + 1;
  2118. X    if (buffer == (char*)1)        /* test for missing '\n' */
  2119. X        break;
  2120. X    }
  2121. X    if (nlines == 0)    /* no records to add */
  2122. X    return;
  2123. X    qsort((char*)line, (unsigned)nlines, sizeof(int), compar);
  2124. X    fnum = ' ';
  2125. X    for (i=0; i<nlines; ++i) {
  2126. X    if (*(line[i]) != fnum) {    /* check for same file */
  2127. X        if (fnum != ' ') {  /* not first time */
  2128. X        fclose(akfile);
  2129. X        }
  2130. X        fnum = *line[i];
  2131. X        sprintf(akname, "%s%s.ak%c", datadir, dbname, fnum);
  2132. X        if((akfile = fopen(akname, "a+")) == NULL) {
  2133. X        msg(strcat("Unable to open file ", akname));
  2134. X        getout();
  2135. X        }
  2136. X    }
  2137. X    fwrite(line[i]+2, strchr(line[i], '\n')-line[i]-2, 1, akfile);
  2138. X    putc('\n', akfile);
  2139. X    }
  2140. X    fclose(akfile);
  2141. X}
  2142. X
  2143. X
  2144. Xcompar(str1, str2)
  2145. Xchar    **str1, **str2;
  2146. X{
  2147. X    return(keycmp(*str1, *str2, AKSIZE));
  2148. X}
  2149. X
  2150. Xkeycmp(s1, s2, len)
  2151. Xregister char    *s1, *s2;
  2152. Xregister int    len;
  2153. X{
  2154. X
  2155. X#ifdef BSD_STRING
  2156. Xregister char    c1, c2;
  2157. X    while (1) {
  2158. X    if (isupper(*s1))
  2159. X        c1 = tolower(*s1);
  2160. X    else
  2161. X        c1 = *s1;
  2162. X    if (isupper(*s2))
  2163. X        c2 = tolower(*s2);
  2164. X    else
  2165. X        c2 = *s2;
  2166. X    if (c1 != c2 || len-- == 0)
  2167. X        break;
  2168. X    if (c1 == '\0')
  2169. X        return(0);
  2170. X    ++s1;
  2171. X    ++s2;
  2172. X    }
  2173. X    return(c1 - c2);
  2174. X#else
  2175. X    while (tolower(*s1) == tolower(*s2) && len--) {
  2176. X    if (*s1 == '\0')
  2177. X        return(0);
  2178. X    ++s1;
  2179. X    ++s2;
  2180. X    }
  2181. X    return(tolower(*s1) - tolower(*s2));
  2182. X#endif
  2183. X}
  2184. SHAR_EOF
  2185. true || echo 'restore of updak.c failed'
  2186. # ============= ascii.h ==============
  2187. echo 'x - extracting ascii.h (Text)'
  2188. sed 's/^X//' << 'SHAR_EOF' > 'ascii.h' &&
  2189. X#ifndef lint
  2190. Xstatic char ID_ascii[] = "@(#)ascii.h    3.1   DeltaDate 8/3/90    ExtrDate 10/6/90";
  2191. X#endif
  2192. X
  2193. X/*      ASCII.H         */
  2194. X/* This defines ASCII control characters as octal numbers */
  2195. X
  2196. X#define NUL     '\000'
  2197. X#define SOH     '\001'
  2198. X#define STX     '\002'
  2199. X#define ETX     '\003'
  2200. X#define EOT     '\004'
  2201. X#define ENQ     '\005'
  2202. X#define ACK     '\006'
  2203. X#define BEL     '\007'
  2204. X#define BS      '\010'
  2205. X#define HT      '\011'
  2206. X#define LF      '\012'
  2207. X#define VT      '\013'
  2208. X#define FF      '\014'
  2209. X#define CR      '\015'
  2210. X#define SO      '\016'
  2211. X#define SI      '\017'
  2212. X#define DLE     '\020'
  2213. X#define DC1     '\021'
  2214. X#define DC2     '\022'
  2215. X#define DC3     '\023'
  2216. X#define DC4     '\024'
  2217. X#define NAK     '\025'
  2218. X#define SYN     '\026'
  2219. X#define ETB     '\027'
  2220. X#define CAN     '\030'
  2221. X#define EM      '\031'
  2222. X#define SUB     '\032'
  2223. X#define ESC     '\033'
  2224. X#define FS      '\034'
  2225. X#define GS      '\035'
  2226. X#define RS      '\036'
  2227. X#define NL      '\037'
  2228. X#define SP      '\040'
  2229. X#define DEL     '\177'
  2230. SHAR_EOF
  2231. true || echo 'restore of ascii.h failed'
  2232. # ============= cardfile.h ==============
  2233. echo 'x - extracting cardfile.h (Text)'
  2234. sed 's/^X//' << 'SHAR_EOF' > 'cardfile.h' &&
  2235. X#ifndef lint
  2236. Xstatic char ID_cardfile[] = "@(#)cardfile.h    3.1   DeltaDate 8/3/90    ExtrDate 10/6/90";
  2237. X#endif
  2238. X
  2239. X/*    CARDFILE.h    */
  2240. X#include    "string.h"
  2241. X
  2242. X#define SWIDTH    80    /* width of screen line */
  2243. X#define    SLENGTH    24    /* length of screen */
  2244. X#define PWIDTH    80    /* width of printer line */
  2245. X#define    MSGLINE    (SLENGTH-2) /* screen message line */
  2246. X#define DBSIZE    1024    /* max size of record in DB file */
  2247. X#define AKSIZE    270    /* max size of record in AK file */
  2248. X#define MAXFLDS    15    /* max number of fields in record */
  2249. X#define FNSIZE    128    /* max size of a file name */
  2250. X#define PLENGTH    66    /* number of lines per page on printer */
  2251. X#define MAXAK    15    /* max number of AK files */
  2252. X#define FLDLEN    256    /* max length of one field */
  2253. X#define TSIZE    20    /* max length of field title */
  2254. X#define BUFSIZE    (2*1024) /* size of buffer used to build AK files */
  2255. X#define MAXKEYS    500    /* maximium keys on one find screen */
  2256. X#define    MAXFMT    128    /* maximum length of a format string */
  2257. X#ifndef TRUE
  2258. X# define TRUE    1
  2259. X# define FALSE    0
  2260. X#endif
  2261. X
  2262. Xtypedef long    diskptr;
  2263. X
  2264. Xstruct Sdata    {    /* structure to describe a screen field */
  2265. X    char    *S_title;
  2266. X    int        S_length;
  2267. X    char    *S_result;
  2268. X    char    *S_dfault;
  2269. X    int        S_page;
  2270. X    int        S_Lrow;
  2271. X    int        S_Lcol;
  2272. X    int        S_Drow;
  2273. X    int        S_Dcol;
  2274. X    char    *S_Dfmt;
  2275. X};
  2276. X
  2277. Xstruct Fdata    {    /* structure to define a data-base field */
  2278. X    char    F_title[TSIZE+1];
  2279. X    char    F_required;
  2280. X    int        F_length;
  2281. X    char    F_key;
  2282. X    char    F_seps[6];
  2283. X    char    F_page;        /* What screen page this field will appear on */
  2284. X    int        F_Lrow;        /* The screen field label row address */
  2285. X    int        F_Lcol;        /* The screen field label column address */
  2286. X    int        F_Drow;        /* The screen field data row address */
  2287. X    int        F_Dcol;        /* The screen field data column address */
  2288. X    char    F_Dfmt[MAXFMT+1];    /* The screen field data format (fmt_chk) */
  2289. X};
  2290. X
  2291. Xstruct AKdata    {    /* structure to hold Alternate Key file info */
  2292. X    int        A_fldnum;
  2293. X    char    A_akname[FNSIZE+1];
  2294. X};
  2295. X
  2296. Xstruct    cchar {        /* strings received from terminal */
  2297. X    char    ch;
  2298. X    int        (*action)();
  2299. X    struct    cchar *next;
  2300. X    struct    cchar *alt;
  2301. X};
  2302. X
  2303. Xextern char    datadir[];
  2304. XSIGRTN        getout();
  2305. Xvoid        exit(), free();
  2306. Xunsigned    sleep();
  2307. Xchar        *tparm();
  2308. SHAR_EOF
  2309. true || echo 'restore of cardfile.h failed'
  2310. # ============= library.def ==============
  2311. echo 'x - extracting library.def (Text)'
  2312. sed 's/^X//' << 'SHAR_EOF' > 'library.def' &&
  2313. Xlibrary.db:8
  2314. XTitle:0:;:Y:65
  2315. XType:1::N:35
  2316. XAuthor:2:;:Y:37
  2317. XKeywords:3:,:N:130
  2318. XPublisher:N::N:20
  2319. XDate:N::N:10
  2320. XCost:N::N:6
  2321. XComments:N::N:250
  2322. X4
  2323. X0:library.ak0
  2324. X1:library.ak1
  2325. X2:library.ak2
  2326. X3:library.ak3
  2327. X%%
  2328. X5:1:::::^1[89][0-9][0-9]$
  2329. X6:1:::::^[0-9]*.[0-9][0-9]$
  2330. SHAR_EOF
  2331. true || echo 'restore of library.def failed'
  2332. true || echo 'restore of library.db failed'
  2333. echo End of part 2, continue with part 3
  2334. exit 0
  2335.  
  2336.  
  2337.